using GroupSix.Application.Dtos;
using GroupSix.Application.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Security.Claims;
using GroupSix.Api.Attributes;
using OperationLogQueryDto = GroupSix.Domain.Repositories.OperationLogQueryDto;

namespace GroupSix.Api.Controllers;

/// <summary>
/// 操作日志控制器
/// </summary>
[ApiController]
[Route("api/[controller]")]
// [RequirePermission("operationlog")] // 暂时注释掉权限验证，用于测试
public class OperationLogController : ControllerBase
{
    private readonly OperationLogService _operationLogService;
    private readonly ILogger<OperationLogController> _logger;

    public OperationLogController(OperationLogService operationLogService, ILogger<OperationLogController> logger)
    {
        _operationLogService = operationLogService;
        _logger = logger;
    }

    /// <summary>
    /// 获取操作日志列表
    /// </summary>
    /// <param name="query">查询条件</param>
    /// <returns>操作日志列表</returns>
    [HttpGet("list")]
    public async Task<IActionResult> GetOperationLogs([FromQuery] OperationLogQueryDto query)
    {
        try
        {
            var result = await _operationLogService.GetOperationLogsAsync(query);
            return Ok(new { success = true, data = result, message = "获取操作日志列表成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取操作日志列表失败");
            return StatusCode(500, new { success = false, message = "获取操作日志列表失败" });
        }
    }

    /// <summary>
    /// 根据操作人获取日志列表
    /// </summary>
    /// <param name="operatorId">操作人ID</param>
    /// <param name="page">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <returns>日志列表</returns>
    [HttpGet("operator/{operatorId}")]
    public async Task<IActionResult> GetLogsByOperator(Guid operatorId, int page = 1, int pageSize = 20)
    {
        try
        {
            var result = await _operationLogService.GetLogsByOperatorAsync(operatorId, page, pageSize);
            return Ok(new { success = true, data = result, message = "获取操作人日志成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取操作人日志失败");
            return StatusCode(500, new { success = false, message = "获取操作人日志失败" });
        }
    }

    /// <summary>
    /// 根据操作类型获取日志列表
    /// </summary>
    /// <param name="operationType">操作类型</param>
    /// <param name="page">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <returns>日志列表</returns>
    [HttpGet("type/{operationType}")]
    public async Task<IActionResult> GetLogsByOperationType(string operationType, int page = 1, int pageSize = 20)
    {
        try
        {
            var result = await _operationLogService.GetLogsByOperationTypeAsync(operationType, page, pageSize);
            return Ok(new { success = true, data = result, message = "获取操作类型日志成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取操作类型日志失败");
            return StatusCode(500, new { success = false, message = "获取操作类型日志失败" });
        }
    }

    /// <summary>
    /// 根据模块获取日志列表
    /// </summary>
    /// <param name="module">模块</param>
    /// <param name="page">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <returns>日志列表</returns>
    [HttpGet("module/{module}")]
    public async Task<IActionResult> GetLogsByModule(string module, int page = 1, int pageSize = 20)
    {
        try
        {
            var result = await _operationLogService.GetLogsByModuleAsync(module, page, pageSize);
            return Ok(new { success = true, data = result, message = "获取模块日志成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取模块日志失败");
            return StatusCode(500, new { success = false, message = "获取模块日志失败" });
        }
    }

    /// <summary>
    /// 根据时间范围获取日志列表
    /// </summary>
    /// <param name="startTime">开始时间</param>
    /// <param name="endTime">结束时间</param>
    /// <param name="page">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <returns>日志列表</returns>
    [HttpGet("timerange")]
    public async Task<IActionResult> GetLogsByTimeRange(DateTime startTime, DateTime endTime, int page = 1, int pageSize = 20)
    {
        try
        {
            var result = await _operationLogService.GetLogsByTimeRangeAsync(startTime, endTime, page, pageSize);
            return Ok(new { success = true, data = result, message = "获取时间范围日志成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取时间范围日志失败");
            return StatusCode(500, new { success = false, message = "获取时间范围日志失败" });
        }
    }

    /// <summary>
    /// 获取最近的日志列表
    /// </summary>
    /// <param name="page">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <returns>日志列表</returns>
    [HttpGet("recent")]
    public async Task<IActionResult> GetRecentLogs(int page = 1, int pageSize = 20)
    {
        try
        {
            var result = await _operationLogService.GetRecentLogsAsync(page, pageSize);
            return Ok(new { success = true, data = result, message = "获取最近日志成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取最近日志失败");
            return StatusCode(500, new { success = false, message = "获取最近日志失败" });
        }
    }

    /// <summary>
    /// 导出日志
    /// </summary>
    /// <param name="request">导出请求</param>
    /// <returns>导出文件</returns>
    [HttpPost("export")]
    // [RequireAdmin] // 暂时注释掉权限验证，用于测试
    public async Task<IActionResult> ExportLogs([FromBody] ExportLogsRequestDto request)
    {
        try
        {
            var logs = await _operationLogService.ExportLogsAsync(request);
            
            // 根据格式返回不同的文件
            switch (request.Format.ToLower())
            {
                case "json":
                    return File(
                        System.Text.Encoding.UTF8.GetBytes(System.Text.Json.JsonSerializer.Serialize(logs, new System.Text.Json.JsonSerializerOptions { WriteIndented = true })),
                        "application/json",
                        $"{request.FileName}.json"
                    );
                
                case "csv":
                    var csvContent = ConvertToCsv(logs);
                    return File(
                        System.Text.Encoding.UTF8.GetBytes(csvContent),
                        "text/csv",
                        $"{request.FileName}.csv"
                    );
                
                default: // excel
                    var excelContent = ConvertToExcel(logs);
                    return File(
                        excelContent,
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                        $"{request.FileName}.xlsx"
                    );
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "导出日志失败: {Format}", request.Format);
            return StatusCode(500, new { success = false, message = "导出日志失败" });
        }
    }

    /// <summary>
    /// 创建操作日志（内部使用）
    /// </summary>
    /// <param name="request">创建请求</param>
    /// <returns>创建结果</returns>
    [HttpPost("create")]
    public async Task<IActionResult> CreateOperationLog([FromBody] CreateOperationLogRequestDto request)
    {
        try
        {
            var result = await _operationLogService.CreateOperationLogAsync(request);
            if (result)
            {
                return Ok(new { success = true, message = "操作日志创建成功" });
            }
            else
            {
                return BadRequest(new { success = false, message = "操作日志创建失败" });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建操作日志失败");
            return StatusCode(500, new { success = false, message = "创建操作日志失败" });
        }
    }

    /// <summary>
    /// 清理过期日志
    /// </summary>
    /// <param name="request">清理请求</param>
    /// <returns>清理结果</returns>
    [HttpPost("cleanup")]
    // [RequireAdmin] // 暂时注释掉权限验证，用于测试
    public async Task<IActionResult> CleanupExpiredLogs([FromBody] CleanupLogsRequestDto request)
    {
        try
        {
            // 参数验证
            if (request.BeforeDate == default)
            {
                return BadRequest(new { success = false, message = "请指定清理日期" });
            }

            // 防止清理太新的日志（至少保留7天）
            var minRetentionDate = DateTime.UtcNow.AddDays(-7);
            if (request.BeforeDate > minRetentionDate)
            {
                return BadRequest(new { 
                    success = false, 
                    message = $"为了数据安全，不能清理 {minRetentionDate:yyyy-MM-dd} 之后的日志" 
                });
            }

            var result = await _operationLogService.CleanupExpiredLogsAsync(request.BeforeDate);
            if (result)
            {
                // 获取清理统计信息
                var cleanupStats = await _operationLogService.GetCleanupStatisticsAsync(request.BeforeDate);
                
                return Ok(new { 
                    success = true, 
                    message = $"清理过期日志成功，共清理 {cleanupStats.CleanedCount} 条日志",
                    data = cleanupStats
                });
            }
            else
            {
                return BadRequest(new { success = false, message = "清理过期日志失败" });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清理过期日志失败");
            return StatusCode(500, new { success = false, message = "清理过期日志失败" });
        }
    }

    /// <summary>
    /// 获取日志统计信息
    /// </summary>
    /// <param name="startDate">开始日期</param>
    /// <param name="endDate">结束日期</param>
    /// <returns>统计信息</returns>
    [HttpGet("statistics")]
    public async Task<IActionResult> GetLogStatistics(DateTime? startDate = null, DateTime? endDate = null)
    {
        try
        {
            var result = await _operationLogService.GetLogStatisticsAsync(startDate, endDate);
            return Ok(new { success = true, data = result, message = "获取日志统计信息成功" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取日志统计信息失败");
            return StatusCode(500, new { success = false, message = "获取日志统计信息失败" });
        }
    }

    /// <summary>
    /// 转换为CSV格式
    /// </summary>
    private string ConvertToCsv(List<OperationLogDto> logs)
    {
        var csv = new System.Text.StringBuilder();
        
        // 添加表头
        csv.AppendLine("ID,操作人ID,操作人,操作类型,模块,描述,结果,IP地址,请求URL,请求方法,响应状态码,执行时间(ms),操作时间");
        
        // 添加数据行
        foreach (var log in logs)
        {
            csv.AppendLine($"\"{log.Id}\",\"{log.OperatorId}\",\"{log.OperatorName}\",\"{log.OperationType}\",\"{log.Module}\",\"{log.Description}\",\"{log.Result}\",\"{log.IpAddress}\",\"{log.RequestUrl}\",\"{log.RequestMethod}\",\"{log.ResponseStatusCode}\",\"{log.ExecutionTime}\",\"{log.OperationTime:yyyy-MM-dd HH:mm:ss}\"");
        }
        
        return csv.ToString();
    }

    /// <summary>
    /// 转换为Excel格式（简化实现，返回CSV格式）
    /// </summary>
    private byte[] ConvertToExcel(List<OperationLogDto> logs)
    {
        // 简化实现：返回CSV格式的字节数组
        // 在实际项目中，可以使用EPPlus或NPOI库生成真正的Excel文件
        var csvContent = ConvertToCsv(logs);
        return System.Text.Encoding.UTF8.GetBytes(csvContent);
    }
} 